package com.wushijia.java8.lambda;

import java.io.IOException;
import java.nio.charset.Charset;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Arrays;
import java.util.function.IntSupplier;
import java.util.stream.IntStream;
import java.util.stream.Stream;

/**
 * description:数值流
 *
 * @author yang
 * @date 2018/5/1 10:42
 */
public class Chapter4 {

  public static void main(String[] args) {
    //IntStream的静态方法：rangeClosed（包含结束数）和range（不包含结束数）
    IntStream intStream = IntStream.rangeClosed(1, 100).filter(n -> n % 2 == 0);
    System.out.println(intStream.count());

    IntStream.rangeClosed(1, 100).boxed().limit(10).flatMap(a -> IntStream.rangeClosed(a, 100).filter(b -> Math.sqrt(a * a + b * b) % 1 == 0)
        .mapToObj(b -> new int[]{a, b, (int) Math.sqrt(a * a + b * b)})).forEach(t -> System.out.println(t[0] + "," + t[1] + "," + t[2]));

    IntStream.rangeClosed(1, 100).boxed().limit(10)
        .flatMap(a -> IntStream.rangeClosed(a, 100).mapToObj(b -> new double[]{a, b, Math.sqrt(a * a + b * b)}))
        .filter(t -> t[2] % 1 == 0).forEach(t -> System.out.println((int) t[0] + "," + (int) t[1] + "," + (int) t[2]));

    //字符串数组创建流
    Stream<String> stringStream = Stream.of("Java 8", "Lambdas ", "In ", "Action");
    stringStream.map(String::toUpperCase).forEach(System.out::println);
    //空流
    Stream<String> emptyStream = Stream.empty();
    //整数数组创建流
    int[] arr = {1, 2, 3, 4, 5};
    int sum = Arrays.stream(arr).sum();
    System.out.println(sum);
    //文件生成流,注意用flatmap来生成扁平流
    long uniqueWords = 0;
    try (Stream<String> lines = Files.lines(Paths.get("data.txt"), Charset.defaultCharset())) {
      uniqueWords = lines.flatMap(line -> Arrays.stream(line.split(" "))).distinct().count();
      System.out.println(uniqueWords);
    } catch (IOException e) {
      e.printStackTrace();
    }

    //函数流：创建无限流，Stream.iterate和Stream.generate,需要用limit来限制
    Stream.iterate(0, x -> x + 2).limit(10).forEach(System.out::println);
    Stream.iterate(new int[]{0, 1}, t -> new int[]{t[1], t[0] + t[1]}).limit(10).map(t -> t[0]).forEach(System.out::println);

    Stream.generate(Math::random).limit(5).forEach(System.out::println);

    //斐波那契数列
    IntSupplier fib = new IntSupplier() {
      private int previous = 0;
      private int current = 1;

      @Override
      public int getAsInt() {
        int oldPrevious = this.previous;
        int nextValue = this.current + this.previous;
        this.previous = this.current;
        this.current = nextValue;
        return oldPrevious;
      }
    };
    IntStream.generate(fib).limit(10).forEach(System.out::println);

    System.out.println(fib(4));
  }

  private static int fib(int count) {
    int[] arr = {0, 1};
    if (count <= 2) {
      return arr[count - 1];
    }

    int pre = 0;
    int curr = 1;
    int fib = 0;
    for (int i = 2; i <= count; i++) {
      fib = pre + curr;
      pre = curr;
      curr = fib;
    }
    return fib;
  }
}
